﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Net.Http;
using System.Web.Http.Filters;
using AdverseEventReportSystem.Utils;

namespace AdverseEventReportSystem.Core {
    /// <summary>
    /// EnableCors特性
    /// </summary>
    [AttributeUsage(AttributeTargets.Class, Inherited = true, AllowMultiple = false)]
    public class EnableCorsAttribute : FilterAttribute {
        public string ErrorMessage { get; private set; }
        public EnableCorsAttribute() {
        }
        public bool TryEvaluate(HttpRequestMessage request, out IDictionary<string, string> headers) {
            headers = null;
            string origin = null;
            try {
                origin = request.Headers.GetValues("Origin").FirstOrDefault();
            } catch (Exception) {
                this.ErrorMessage = "Cross-origin request denied";
                return false;
            }
            string origins = ConfigHelper.GetConfigString("Origins");
            string[] arrOrigin = origins.Split(',');
            if (arrOrigin.Contains(origin)) {
                headers = this.GenerateResponseHeaders(request);
                return true;
            }

            this.ErrorMessage = "Cross-origin request denied";
            return false;
        }

        private IDictionary<string, string> GenerateResponseHeaders(HttpRequestMessage request) {

            //设置响应头"Access-Control-Allow-Methods"

            string origin = request.Headers.GetValues("Origin").First();

            Dictionary<string, string> headers = new Dictionary<string, string>();

            headers.Add("Access-Control-Allow-Origin", origin);

            if (request.IsPreflightRequest()) {
                //设置响应头"Access-Control-Request-Headers"
                //和"Access-Control-Allow-Headers"
                headers.Add("Access-Control-Allow-Methods", "*");
                headers.Add("Access-Control-Allow-Credentials", "true");
                headers.Add("Access-Control-Max-Age", "3600");
                string requestHeaders = request.Headers.GetValues("Access-Control-Request-Headers").FirstOrDefault();

                if (!string.IsNullOrEmpty(requestHeaders)) {
                    headers.Add("Access-Control-Allow-Headers", requestHeaders);
                }
            }
            return headers;
        }
    }

    /// <summary>
    /// HttpRequestMessage扩展方法
    /// </summary>
    public static class HttpRequestMessageExtensions {
        public static bool IsPreflightRequest(this HttpRequestMessage request) {
            return request.Method == HttpMethod.Options
                && request.Headers.GetValues("Origin").Any()
                && request.Headers.GetValues("Access-Control-Request-Method").Any();
        }
    }
}
